using System;

namespace Fadd.Globalization
{
    /// <summary>
    /// Contains language translations used to create multilingual applications
    /// </summary>
    /// <remarks>
    /// The ILanguageNode provides a base class for different implementations of a hierachial language structure
    /// </remarks>
    public interface ILanguageNode
    {
        /// <summary>
        /// Gets the parent language node. 
        /// </summary>
        /// <remarks>
        /// null if no parent node exists.
        /// </remarks>
        ILanguageNode ParentNode { get; }

        /// <summary>
        /// Gets the mother of all nodes.
        /// </summary>
        /// <remarks>
        /// Root node will return itself.
        /// </remarks>
        ILanguageNode RootNode { get; }

        /// <summary>
        /// Gets the number of languages (and not the number of text items).
        /// </summary>
        int Count { get; }

        /// <summary>
        /// Gets the name of this node.
        /// </summary>
        string Name { get; }

        /// <summary>
        /// Gets language to use if the requested language is not found.
        /// </summary>
        int DefaultLCID { get; }

        /// <summary>
        /// Gets a localized text string in the current language.
        /// </summary>
        /// <param name="textName">Phrase to find, can also contain a path.</param>
        /// <returns>text if found; [textName] if not.</returns>
        /// <example>
        /// <code>
        /// lang["Name"] // => "Name"
        /// lang["/Users/View/Name"] // => "Name"
        /// lang["Naem"] // => "[Naem]" since it's missing
        /// </code>
        /// </example>
        string this[string textName]
        {
            get;
        }

        /// <summary>
        /// Gets a localized text string in the specified language.
        /// </summary>
        /// <param name="textName">Phrase to find, can also contain a path.</param>
        /// <param name="lcid">Get translation from this language.</param>
        /// <returns>text if found; [textName] if not.</returns>
        /// <example>
        /// <code>
        /// lang["Name"] // => "Name"
        /// lang["Name"] // => "Name"
        /// lang["Naem"] // => "[Naem]" since it's missing
        /// </code>
        /// </example>
        string this[string textName, int lcid]
        {
            get;
        }

        /// <summary>
        /// Get a text string in the specified language.
        /// </summary>
        /// <param name="lcid">Language to fetch from.</param>
        /// <param name="textName">name of text to find.</param>
        /// <returns>string if found; otherwise null.</returns>
        string GetText(int lcid, string textName);

        /// <summary>
        /// Get a text string in the specified language.
        /// </summary>
        /// <param name="lcid">Language to fetch from.</param>
        /// <param name="textName">name of text to find.</param>
        /// <param name="checkPaths">check for paths in <paramref name="textName"/>.</param>
        /// <returns>string if found; otherwise null.</returns>
        string GetText(int lcid, string textName, bool checkPaths);

        /// <summary>
        /// Gets a sub category
        /// </summary>
        /// <param name="name">The category name</param>
        /// <returns><see cref="ILanguageNode"/> if found; otherwise null.</returns>
        /// <exception cref="ArgumentNullException">If name is null</exception>
        ILanguageNode GetChild(string name);

        /// <summary>
        /// Number of translated texts in the specified language.
        /// </summary>
        /// <param name="lcid">Language to get text from.</param>
        /// <returns>Number of text items</returns>
        int GetTextCount(int lcid);

        /// <summary>
        /// Determine if the node contains a text item with the specified name (for the current lcid)
        /// </summary>
        /// <returns>True if the node contains a language element with the specified name for the current language</returns>
        bool Contains(string name);

        /// <summary>
        /// Determine if the node contains a text item with the specified name for the specified language
        /// </summary>
        /// <returns>True if the node contains a language element with the specified name for the specified language</returns>
        bool Contains(string name, int lcid);

        /// <summary>
        /// Determine if a category contains a specific language.
        /// </summary>
        /// <param name="lcid">Language to get text from.</param>
        /// <returns>true if the specified language contains the text string; false if not.</returns>
        bool ContainsLanguage(int lcid);

        /// <summary>
        /// Checks if current language contains a child node with the specified name.
        /// </summary>
        /// <param name="name">Name of child node</param>
        /// <returns>true if found; otherwise false.</returns>
        bool ContainsChild(string name);

        /// <summary>Empties all saved values in the node and its sub nodes</summary>
        void ClearHierarchy();
    }
}